package com.supermap.desktop.ui.controls;

import java.awt.Component;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.EventObject;

import javax.swing.DefaultCellEditor;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;

import com.supermap.data.Dataset;
import com.supermap.data.DatasetType;
import com.supermap.data.Datasource;
import com.supermap.data.Datasources;
import com.supermap.data.EngineType;
import com.supermap.data.Layouts;
import com.supermap.data.Maps;
import com.supermap.data.Resources;
import com.supermap.data.Scenes;
import com.supermap.data.SymbolFillLibrary;
import com.supermap.data.SymbolLineLibrary;
import com.supermap.data.SymbolMarkerLibrary;
import com.supermap.data.Workspace;
import com.supermap.desktop.controls.ControlsProperties;

/**
 * 工作空间树单元格编辑器
 * 
 * @author xuzw
 *
 */
class WorkspaceTreeCellEditor extends DefaultTreeCellEditor {

	private String stringTextField = null;

	private Workspace currentWorkspace = null;

	public WorkspaceTreeCellEditor(JTree tree, WorkspaceTreeCellRenderer renderer, Workspace workspace) {
		super(tree, renderer);
		currentWorkspace = workspace;
	}

	protected void determineOffset(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {

		// 计算基类的图片偏移量
		if (editingIcon != null)
			offset = renderer.getIconTextGap() + editingIcon.getIconWidth();
		else
			offset = renderer.getIconTextGap();

		drawEditingIcon(value);

	}

	public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {

		// 给相关父类成员赋值
		setTree(tree);
		lastRow = row;

		// 计算offset
		determineOffset(tree, value, isSelected, expanded, leaf, row);

		// 清除editing
		if (null != editingComponent) {
			editingContainer.remove(editingComponent);
		}

		// 有editor返回编译使用的Component
		editingComponent = realEditor.getTreeCellEditorComponent(tree, stringTextField, isSelected, expanded, leaf, row);

		// 计算路径
		TreePath newPath = tree.getPathForRow(row);

		canEdit = (lastPath != null && newPath != null && lastPath.equals(newPath));

		// 赋值
		Font font = getEditFont(tree);

		editingContainer.setFont(font);
		prepareForEditing();

		return editingContainer;
	}

	private Font getEditFont(JTree tree) {
		Font font = getFont();

		if (null == font) {

			if (null != renderer) {
				font = renderer.getFont();
			}

			if (null == font) {
				font = tree.getFont();
			}
		}
		return font;
	}

	public boolean stopCellEditing() {
		TreePath treeSelectionPath = tree.getSelectionPath();
		Object lastComponent = treeSelectionPath.getLastPathComponent();
		DefaultMutableTreeNode tempNode = (DefaultMutableTreeNode) lastComponent;
		TreeNodeData tempNodeData = (TreeNodeData) tempNode.getUserObject();
		try {
			Object data = tempNodeData.getData();
			if (data instanceof Datasource) {
				Datasource datasource = (Datasource) data;
				currentWorkspace.getDatasources().modifyAlias(datasource.getAlias(), stringTextField);

			} else if (data instanceof Dataset) {
				Dataset dataset = (Dataset) data;
				if (!(dataset.getDatasource().getDatasets().rename(dataset.getName(), stringTextField))) {
					stringTextField = dataset.getName();
					cancelCellEditing();
				}
			} else {
				NodeDataType type = tempNodeData.getType();
				if (type.equals(NodeDataType.LAYOUT_NAME)) {
					String layoutName = (String) data;
					currentWorkspace.getLayouts().rename(layoutName, stringTextField);
				} else if (type.equals(NodeDataType.MAP_NAME)) {
					String mapName = (String) data;
					currentWorkspace.getMaps().rename(mapName, stringTextField);
				} else if (type.equals(NodeDataType.SCENE_NAME)) {
					String sceneName = (String) data;
					currentWorkspace.getScenes().rename(sceneName, stringTextField);
				} else {
					cancelCellEditing();
				}
			}
		} catch (RuntimeException e) {
			e.printStackTrace();
		} finally {
			cancelCellEditing();
		}

		if (realEditor.stopCellEditing()) {
			cleanupAfterEditing();
			return true;
		}
		return false;
	}

	/**
	 * Messages <code>cancelCellEditing</code> to the <code>realEditor</code> and removes it from this instance.
	 */
	public void cancelCellEditing() {
		realEditor.cancelCellEditing();
		cleanupAfterEditing();
	}

	/**
	 * Returns the value currently being edited.
	 * 
	 * @return the value currently being edited
	 */
	public Object getCellEditorValue() {

		return realEditor.getCellEditorValue();

		// return realEditor.getCellEditorValue();
	}

	/**
	 * This is invoked if a <code>TreeCellEditor</code> is not supplied in the constructor. It returns a <code>TextField</code> editor.
	 * 
	 * @return a new <code>TextField</code> editor
	 */
	@SuppressWarnings("serial")
	protected TreeCellEditor createTreeCellEditor() {
		Border aBorder = UIManager.getBorder("Tree.editorBorder");
		DefaultTextField defaultTextField = new DefaultTextField(aBorder);
		defaultTextField.addKeyListener(new KeyListener() {
			public void keyPressed(KeyEvent e) {
				int keyCode = e.getKeyChar();
				if (keyCode == KeyEvent.VK_ENTER) {
					Object obj = realEditor.getCellEditorValue();
					stringTextField = obj.toString();

					fireStopCellEditing();
					tree.updateUI();
				}
			}

			public void keyReleased(KeyEvent e) {/* Nonthing to do! */
			}

			public void keyTyped(KeyEvent e) {/* Nonthing to do! */
			}
		});

		DefaultCellEditor editor = new DefaultCellEditor(defaultTextField) {
			public boolean shouldSelectCell(EventObject event) {
				boolean retValue = super.shouldSelectCell(event);
				return retValue;
			}
		};
		// One click to edit.
		editor.setClickCountToStart(1);
		return editor;
	}

	private void cleanupAfterEditing() {
		if (editingComponent != null) {
			editingContainer.remove(editingComponent);
		}
		editingComponent = null;
	}

	private void fireStopCellEditing() {
		stopCellEditing();
	}

	private void drawEditingIcon(Object value) {
		DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode) value;
		TreeNodeData tempNodeData = (TreeNodeData) defaultMutableTreeNode.getUserObject();
		Object data = tempNodeData.getData();
		if (data instanceof Workspace) {
			editingIcon = InternalImageIconFactory.WORKSPACE;
			if (currentWorkspace.getCaption().equals("UntitledWorkspace")) {
				stringTextField = ControlsProperties.getString(ControlsProperties.WorkspaceNodeDefaultName);
			} else {
				stringTextField = currentWorkspace.getCaption();
			}
		} else if (data instanceof Datasources) {
			editingIcon = InternalImageIconFactory.DATASOURCES;
			stringTextField = ControlsProperties.getString(ControlsProperties.DatasourcesNodeName);
		} else if (data instanceof Datasource) {
			Datasource tempDatasource = (Datasource) tempNodeData.getData();
			EngineType engineType = tempDatasource.getEngineType();
			if (engineType.equals(EngineType.SQLPLUS)) {
				editingIcon = InternalImageIconFactory.DATASOURCE_SQL;
			} else if (engineType.equals(EngineType.IMAGEPLUGINS)) {
				editingIcon = InternalImageIconFactory.DATASOURCE_IMAGEPLUGINS;
			} else if (engineType.equals(EngineType.OGC)) {
				editingIcon = InternalImageIconFactory.DATASOURCE_OGC;
			} else if (engineType.equals(EngineType.ORACLEPLUS)) {
				editingIcon = InternalImageIconFactory.DATASOURCE_ORACLE;
			} else if (engineType.equals(EngineType.UDB)) {
				editingIcon = InternalImageIconFactory.DATASOURCE_UDB;
			}
			stringTextField = tempDatasource.getAlias();
		} else if (data instanceof Dataset) {
			Dataset tempDataset = (Dataset) tempNodeData.getData();
			DatasetType instanceDatasetType = tempDataset.getType();
			if (instanceDatasetType.equals(DatasetType.POINT)) {
				editingIcon = InternalImageIconFactory.DT_POINT;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.LINE)) {
				editingIcon = InternalImageIconFactory.DT_LINE;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.LINEM)) {
				editingIcon = InternalImageIconFactory.DT_LINEM;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.REGION)) {
				editingIcon = InternalImageIconFactory.DT_REGION;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.CAD)) {
				editingIcon = InternalImageIconFactory.DT_CAD;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.GRID)) {
				editingIcon = InternalImageIconFactory.DT_GRID;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.IMAGE)) {
				editingIcon = InternalImageIconFactory.DT_IMAGE;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.LINKTABLE)) {
				editingIcon = InternalImageIconFactory.DT_LINKTABLE;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.NETWORK)) {
				editingIcon = InternalImageIconFactory.DT_NETWORK;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.TABULAR)) {
				editingIcon = InternalImageIconFactory.DT_TABULAR;
				stringTextField = tempDataset.getName();
				// } else if (instanceDatasetType.equals(DatasetType.RELATIONSHIP)) {
				// editingIcon = InternalImageIconFactory.DT_RELATIONSHIP;
				// m_textField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.TEXT)) {
				editingIcon = InternalImageIconFactory.DT_TEXT;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.TOPOLOGY)) {
				editingIcon = InternalImageIconFactory.DT_TOPOLOGY;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.WCS)) {
				editingIcon = InternalImageIconFactory.DT_WCS;
				stringTextField = tempDataset.getName();
			} else if (instanceDatasetType.equals(DatasetType.WMS)) {
				editingIcon = InternalImageIconFactory.DT_WMS;
				stringTextField = tempDataset.getName();
			}
		} else if (data instanceof Maps) {
			editingIcon = InternalImageIconFactory.MAPS;
			stringTextField = ControlsProperties.getString(ControlsProperties.MapsNodeName);
		} else if (tempNodeData.getType().equals(NodeDataType.MAP_NAME)) {
			editingIcon = InternalImageIconFactory.MAP;
			stringTextField = tempNodeData.getData().toString().trim();
		} else if (data instanceof Scenes) {
			editingIcon = InternalImageIconFactory.SCENES;
			stringTextField = ControlsProperties.getString(ControlsProperties.ScenesNodeName);
		} else if (tempNodeData.getType().equals(NodeDataType.SCENE_NAME)) {
			editingIcon = InternalImageIconFactory.SCENE;
			stringTextField = tempNodeData.getData().toString().trim();
		} else if (data instanceof Layouts) {
			editingIcon = InternalImageIconFactory.LAYOUTS;
			stringTextField = ControlsProperties.getString(ControlsProperties.LayoutsNodeName);
		} else if (tempNodeData.getType().equals(NodeDataType.LAYOUT_NAME)) {
			editingIcon = InternalImageIconFactory.LAYOUT;
			stringTextField = tempNodeData.getData().toString().trim();
		} else if (data instanceof Resources) {
			editingIcon = InternalImageIconFactory.RESOURCES;
			stringTextField = ControlsProperties.getString(ControlsProperties.ResourcesNodeName);
		} else if (data instanceof SymbolMarkerLibrary) {
			editingIcon = InternalImageIconFactory.SYMBOLMARKERLIB;
			stringTextField = ControlsProperties.getString(ControlsProperties.SymbolMarkerLibNodeName);
		} else if (data instanceof SymbolLineLibrary) {
			editingIcon = InternalImageIconFactory.SYMBOLLINELIB;
			stringTextField = ControlsProperties.getString(ControlsProperties.SymbolLineLibNodeName);
		} else if (data instanceof SymbolFillLibrary) {
			editingIcon = InternalImageIconFactory.SYMBOLFillLIB;
			stringTextField = ControlsProperties.getString(ControlsProperties.SymbolFillLibNodeName);
		}
	}

}
